package jp.sinmetal.trainer.action;

import javax.annotation.Resource;
import javax.servlet.http.HttpSession;

import jp.sinmetal.trainer.entity.Member;
import jp.sinmetal.trainer.form.AuthenticationForm;
import jp.sinmetal.trainer.service.MemberService;
import jp.sinmetal.trainer.util.TwitterUtil;

import org.seasar.framework.aop.annotation.RemoveSession;
import org.seasar.framework.beans.util.Beans;
import org.seasar.struts.annotation.ActionForm;
import org.seasar.struts.annotation.Execute;

import twitter4j.User;
import twitter4j.http.AccessToken;
import twitter4j.http.RequestToken;

/**
 * 認証アクション
 * @author sin
 *
 */
public class AuthenticationAction extends AbstractAction {

	/**
	 * 認証アクションフォーム
	 * @author sin
	 */
	@ActionForm
	@Resource
	public AuthenticationForm authenticationForm;

	/**
	 * Session情報
	 * @author sin
	 */
	@Resource
	protected HttpSession session;

	/**
	 * メンバーサービス
	 * @author sin
	 */
	@Resource
	protected MemberService memberService;

	/**
	 * エントリーポイント
	 * Twitter認証
	 * @author sin
	 *
	 * @return
	 */
	@Execute(validator = false, redirect = true)
    public String index() {
		Member member = findMemberByCookie();
		if (member != null) {
			TwitterUtil twitterUtil = new TwitterUtil();
			twitterUtil.setOAuthAccessToken(member.twitterToken, member.twitterTokenSecret);
			saveMember(twitterUtil);
			return "/convention";
		} else {
			RequestToken requestToken = TwitterUtil.createRequestToken();
			session.setAttribute("requestToken", requestToken);
			return requestToken.getAuthorizationURL();
		}
    }

	/**
	 * ログイン
	 * @author sin
	 *
	 * @return
	 */
	@Execute(validator = false, redirect = true)
	public String login() {
		TwitterUtil twitterUtil = new TwitterUtil();
		RequestToken requestToken = (RequestToken)session.getAttribute("requestToken");
		twitterUtil.getOAuthAccessToken(requestToken);
		saveMember(twitterUtil);
		return "/convention";
	}

	/**
	 * ログアウト
	 * @author sin
	 *
	 * @return
	 */
	@Execute(validator = false, redirect = true)
	@RemoveSession(name = "memberInfo")
	public String logout() {
		return "/convention";
	}

	/**
	 * クッキー情報からメンバーを取得
	 * @author sin
	 *
	 * @return
	 */
	protected Member findMemberByCookie() {
		// TODO Cookieから識別情報を取得し、DBからAccessTokenを取得する
//		Integer id = 159815155; //PokemonMS
//		Integer id = 26903289; //sinmetal
//		return memberService.findByTwitterId(id);
		return null;
	}

	/**
	 * メンバー情報保存
	 * @author sin
	 *
	 * @param twitterUtil
	 */
	protected void saveMember(TwitterUtil twitterUtil) {
		User user = twitterUtil.getUser();
		Member member = memberService.findByTwitterId(user.getId());
		if (member == null) {
			insertMember(user,twitterUtil.getOAuthAccessToken());
		} else {
			updateMember(member, user,twitterUtil.getOAuthAccessToken());
		}
	}

	/**
	 * メンバー作成
	 * @author sin
	 *
	 * @param user
	 * @param accessToken
	 * @return
	 */
	protected int insertMember(User user, AccessToken accessToken) {
		Member member = new Member();
		member.setTwitterInfo(user, accessToken);
		int ret = memberService.insertMember(member);
		setMemberInfo(member);
		return ret;
	}

	/**
	 * メンバー更新
	 * @author sin
	 *
	 * @param user
	 * @param accessToken
	 * @return
	 */
	protected int updateMember(Member currentMember, User user, AccessToken accessToken) {
		Member member = Beans.createAndCopy(Member.class, currentMember).execute();
		member.setTwitterInfo(user, accessToken);
		int ret = memberService.updateMemberChangedFrom(member, currentMember);
		setMemberInfo(member);
		return ret;
	}

	/**
	 * メンバー情報設定
	 * @author sin
	 *
	 * @param member
	 */
	protected void setMemberInfo(Member member) {
		Beans.copy(member, memberInfo).execute();
	}
}
